﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;

namespace Spellmaker
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        internal bool areaPadrao = true;

        private BitmapImage CreateNullImage()
        {
            BitmapImage img = new BitmapImage();
            MemoryStream ms = new MemoryStream();
            Properties.Resources._null.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
            img.BeginInit();
            img.StreamSource = ms;
            img.EndInit();
            return img;
        }

        private BitmapImage NullImage = new BitmapImage();

        internal class DamageType
        {
            public string Name { get; set; }
            public string Param { get; set; }
        }

        internal class Formula
        {
            public string Name { get; set; }
            public string Param { get; set; }
        }

        internal class AreaEffect
        {
            public string Name { get; set; }
            public string Param { get; set; }
            public BitmapImage Image { get; set; }
        }

        internal class DistanceEffect
        {
            public string Name { get; set; }
            public string Param { get; set; }
            public BitmapImage Image { get; set; }
        }

        internal class Option
        {
            public string Name { get; set; }
            public string Argument { get; set; }
            public bool IsChecked { get; set; }
        }

        internal class Vocation
        {
            public string Name { get; set; }
            public bool IsChecked { get; set; }
        }

        /*public class ConditionParam
        {
            public string Name { get; set; }
            public string Param { get; set; }
            public string Value { get; set; }
        }

        public class Condition
        {
            public string Name { get; set; }
            public string Param { get; set; }
            public List<ConditionParam> ConditionParams { get; set; }
        }*/

        internal class DefaultArea
        {
            public string Name { get; set; }
            public string Param { get; set; }
        }

        private void LoadVocations()
        {
            XmlReader rdr = XmlReader.Create(Directory.GetCurrentDirectory() + "\\vocations.xml");
            List<Vocation> Vocations = new List<Vocation>();
            while (rdr.Read())
            {
                if (rdr.NodeType == XmlNodeType.Element && rdr.Name == "vocation")
                {
                    Vocations.Add(new Vocation { Name = rdr.GetAttribute(2), IsChecked = false });
                }
            }
            lboxVocacoes.ItemsSource = Vocations;
        }

        private void LoadDamageTypes()
        {
            XmlReader rdr = XmlReader.Create(Directory.GetCurrentDirectory() + "\\damagetypes.xml");
            List<DamageType> DamageTypes = new List<DamageType>();
            while (rdr.Read())
            {
                if (rdr.NodeType == XmlNodeType.Element && rdr.Name == "damagetype")
                {
                    DamageTypes.Add(new DamageType { Name = rdr.GetAttribute("name"), Param = rdr.GetAttribute("param") });
                }
            }
            lboxDamageType.ItemsSource = DamageTypes;
        }

        private void LoadFormulas()
        {
            XmlReader rdr = XmlReader.Create(Directory.GetCurrentDirectory() + "\\formulas.xml");
            List<Formula> Formulas = new List<Formula>();
            while (rdr.Read())
            {
                if (rdr.NodeType == XmlNodeType.Element && rdr.Name == "formula")
                {
                    Formulas.Add(new Formula { Name = rdr.GetAttribute("name"), Param = rdr.GetAttribute("param") });
                }
            }
            lboxFormula.ItemsSource = Formulas;
        }

        private void LoadAreaEffects()
        {
            XmlReader rdr = XmlReader.Create(Directory.GetCurrentDirectory() + "\\areaeffects.xml");
            List<AreaEffect> AreaEffects = new List<AreaEffect>();
            while (rdr.Read())
            {
                if (rdr.NodeType == XmlNodeType.Element && rdr.Name == "areaeffect")
                {
                    AreaEffects.Add(new AreaEffect { Name = rdr.GetAttribute("name"), Param = rdr.GetAttribute("param"), Image = ((File.Exists(Directory.GetCurrentDirectory() + "\\areaeffects\\" + rdr.GetAttribute("param") + ".png")) ? new BitmapImage(new Uri(Directory.GetCurrentDirectory() + "\\areaeffects\\" + rdr.GetAttribute("param") + ".png")) : NullImage) });
                }
            }
            lboxAreaEffect.ItemsSource = AreaEffects;
        }

        private void LoadDistanceEffects()
        {
            XmlReader rdr = XmlReader.Create(Directory.GetCurrentDirectory() + "\\distanceeffects.xml");
            List<DistanceEffect> DistanceEffects = new List<DistanceEffect>();
            while (rdr.Read())
            {
                if (rdr.NodeType == XmlNodeType.Element && rdr.Name == "distanceeffect")
                {
                    DistanceEffects.Add(new DistanceEffect { Name = rdr.GetAttribute("name"), Param = rdr.GetAttribute("param"), Image = ((File.Exists(Directory.GetCurrentDirectory() + "\\distanceeffects\\" + rdr.GetAttribute("param") + ".png")) ? new BitmapImage(new Uri(Directory.GetCurrentDirectory() + "\\distanceeffects\\" + rdr.GetAttribute("param") + ".png")) : NullImage) });
                }
            }
            lboxDistanceEffect.ItemsSource = DistanceEffects;
        }

        /*public void LoadConditions()
        {
            XmlReader rdr = XmlReader.Create(Directory.GetCurrentDirectory() + "\\conditions.xml");
            List<Condition> Conditions = new List<Condition>();
            string c = string.Empty;
            while (rdr.Read())
            {
                if (rdr.NodeType == XmlNodeType.Element)
                {
                    if (rdr.Name == "condition")
                    {
                        Conditions.Add(new Condition { Name = rdr.GetAttribute("name"), Param = rdr.GetAttribute("param") });
                        c = rdr.GetAttribute("param");
                    }
                    else if (rdr.Name == "param")
                    {
                        Conditions.Find(delegate(Condition _c) { return _c.Param == c; }).ConditionParams.Add(new ConditionParam { Name = rdr.GetAttribute("name"), Param = rdr.GetAttribute("param")});
                    }
                }
            }
            cboxConditions.ItemsSource = Conditions;
        }*/

        private void LoadDefaultAreas()
        {
            XmlReader rdr = XmlReader.Create(Directory.GetCurrentDirectory() + "\\defaultareas.xml");
            List<DefaultArea> DefaultAreas = new List<DefaultArea>();
            while (rdr.Read())
            {
                if (rdr.NodeType == XmlNodeType.Element && rdr.Name == "defaultarea")
                {
                    DefaultAreas.Add(new DefaultArea { Name = rdr.GetAttribute("name"), Param = rdr.GetAttribute("param") });
                }
            }
            lboxAreas.ItemsSource = DefaultAreas;
        }

        /// <summary>
        /// Initializes the main screen of main window.
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
            NullImage = CreateNullImage();
            LoadVocations();
            LoadDamageTypes();
            LoadFormulas();
            LoadAreaEffects();
            LoadDistanceEffects();
            //LoadConditions();
            LoadDefaultAreas();
        }

        private void formMain_Loaded(object sender, RoutedEventArgs e)
        {
            //tblkFormula.Text = "(level / campo 1)\n+\n(magic level * campo 2)";
            List<Option> Options = new List<Option>() {
                new Option { Name = "Agressiva", Argument = "aggressive", IsChecked = true },
                new Option { Name = "Direcionada", Argument = "direction", IsChecked = false },
                new Option { Name = "Não atravessa paredes", Argument = "blockwalls", IsChecked = false },
                new Option { Name = "Precisa de alvo", Argument = "needtarget", IsChecked = false },
                new Option { Name = "Precisa de arma", Argument = "needweapon", IsChecked = false },
                new Option { Name = "Precisa aprender", Argument = "needlearn", IsChecked = false },
            };
            lboxOpcoes.ItemsSource = Options;
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            System.Text.RegularExpressions.Regex txt = new System.Text.RegularExpressions.Regex("^([a-zA-Z0-9])$"), num = new System.Text.RegularExpressions.Regex("^([0-9])$");
            if (!txt.IsMatch(tboxNome.Text) && MessageBox.Show("O nome da spell é inválido!\nPreencha o campo \"Nome\" corretamente.\nContinuar?", "Erro", MessageBoxButton.YesNo, MessageBoxImage.Information, MessageBoxResult.No) == MessageBoxResult.No) return;
            if (!txt.IsMatch(tboxPalavras.Text) && MessageBox.Show("As palavras da spell são inválidas!\nPreencha o campo \"Palavras\" corretamente.\nContinuar?", "Erro", MessageBoxButton.YesNo, MessageBoxImage.Information, MessageBoxResult.No) == MessageBoxResult.No) return;
            if (!num.IsMatch(tboxLevel.Text) && MessageBox.Show("O level mínimo da spell é inválido!\nPreencha o campo \"Level\" corretamente.\nContinuar?", "Erro", MessageBoxButton.YesNo, MessageBoxImage.Information, MessageBoxResult.No) == MessageBoxResult.No) return;
            if (!num.IsMatch(tboxML.Text) && MessageBox.Show("O magic level mínimo da spell é inválido!\nPreencha o campo \"ML\" corretamente.\nContinuar?", "Erro", MessageBoxButton.YesNo, MessageBoxImage.Information, MessageBoxResult.No) == MessageBoxResult.No) return;
            if (!num.IsMatch(tboxMana.Text) && MessageBox.Show("A mana necessária da spell é inválida!\nPreencha o campo \"Mana\" corretamente.\nContinuar?", "Erro", MessageBoxButton.YesNo, MessageBoxImage.Information, MessageBoxResult.No) == MessageBoxResult.No) return;
            if (!num.IsMatch(tboxSoul.Text) && MessageBox.Show("O soul necessário da spell é inválido!\nPreencha o campo \"Soul\" corretamente.\nContinuar?", "Erro", MessageBoxButton.YesNo, MessageBoxImage.Information, MessageBoxResult.No) == MessageBoxResult.No) return;
            if ((!num.IsMatch(tboxMin1.Text) || !num.IsMatch(tboxMin2.Text))  && MessageBox.Show("O dano mínimo da spell é inválido!\nPreencha os campos \"Mínimo\" corretamente.\nContinuar?", "Erro", MessageBoxButton.YesNo, MessageBoxImage.Information, MessageBoxResult.No) == MessageBoxResult.No) return;
            if ((!num.IsMatch(tboxMax1.Text) || !num.IsMatch(tboxMax2.Text)) && MessageBox.Show("O dano máximo da spell é inválido!\nPreencha os campos \"Máximo\" corretamente.\nContinuar?", "Erro", MessageBoxButton.YesNo, MessageBoxImage.Information, MessageBoxResult.No) == MessageBoxResult.No) return;
            ScriptWindow formScript = new ScriptWindow(this);
            formScript.ShowDialog();
        }

        private void lboxAreas_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            areaPadrao = true;
        }

        private void CreateAreaSelected(object sender, RoutedEventArgs e)
        {
            areaPadrao = false;
            lboxAreas.SelectedIndex = -1;
        }     
    }
}
